#ifndef TYPEINFO_H
#define TYPEINFO_H

#include <vector>
#include "jncDefs.h"
#include "jncInterface.h"
#include <string>
#include "jncFntHandlerDb.h"

// Compile type info and Runtime info for a given object

class CplInfo {
 public:
  CplInfo():id(UNSET) {}
    CplInfo(Idnb i, std::vector<CplInfo> args): id(i), argi(args) {}
      CplInfo(Idnb i) : id(i) {}
      CplInfo& operator = (CplInfo x)
	{
	  id = x.getId();
	  pr = x.getPriority();
	  nm = x.getSymbolicName();
	  typ = x.getType();
	  argi = x.getArgInfo();
	}
      Idnb getId() const 
      { return id;}
      void setPriority(Priority p)
      { pr = p;}
      Priority getPriority()
      { return pr;}
      void setSymbolicName(std::string s)
      { nm = s; }
      inline std::string getSymbolicName() const
	{ 
	  return nm;
	}
      inline void setType(jncTypei t)
	{ typ = t; }
      inline jncTypei getType() const
	{ 
	  return typ;
	}
      inline void setArgInfo(std::vector<CplInfo>& args)
	{ argi = args; }
      inline std::vector<CplInfo>& getArgInfo()
	{ 
	  return argi;
	}
 private:
      Idnb id;
      Priority pr;
      std::string nm;
      jncTypei typ;
      std::vector<CplInfo> argi;
};

class RtmInfo {
 public:
  RtmInfo(Idnb i = UNSET): stat(INCOMPLETE), ptr_ob(NULL), getter(NULL), setter(NULL), id(i){}
    RtmInfo(Idnb i, JncInterface* p_ob, void* get, void* set) : ptr_ob(p_ob), getter(get), setter(set), id(i)
      {
	(!ptr_ob || !setter)? stat = INCOMPLETE: stat = COMPLETE;
	
      }
      ~RtmInfo() {}
	
      inline virtual RtmInfo& operator = (RtmInfo& x)
	{
	  id = x.getId();
	  stat = x.getState();
	  ptr_ob = x.getObject();
	  getter = x.getHandle();
	  setter = x.getfn();
	  ret = x.getResult();
	  if(x.getArg().size())
	    {
	      std::vector<RtmInfo> tmp(x.getArg());
	      argv.clear();
	      argv.insert(argv.begin(), tmp.begin(), tmp.end());
	    }
	  return *this;
	}
      inline void setState(RunState r)
	{
	  stat = r;
	}
      inline virtual RunState getState()
	{ 
	  return stat;
	}
      inline virtual JncInterface* getObject()
	{ return ptr_ob;}
      inline virtual void* getHandle()
	{return static_cast<void*>(getter);}
      virtual void setReturn();
      virtual gReturnCode getResult()
      { return ret;}
      inline virtual void* getfn()
	{return static_cast<void*>(setter);}
      inline virtual std::vector<RtmInfo>& getArg()
	{ return argv;}
      inline virtual void setArg(std::vector<RtmInfo>& v)
	{
	  argv.clear();
	  argv.insert(argv.begin(), v.begin(), v.end());
	}
      friend gReturnCode forceReturn(RtmInfo*, gReturnCode&);
      Idnb getId() {
	return id;
      }
 protected:
      JncInterface* ptr_ob;
      gnCallback getter;
      gnCallback setter;
      RunState stat;
      gReturnCode ret;
      std::vector<RtmInfo> argv;
      Idnb id;
};

struct RuntimeObject {
  RuntimeObject(const CplInfo& c, const RtmInfo& r):oci(new CplInfo(c)), ori(new RtmInfo(r)) {}
  RuntimeObject(){}
  inline RuntimeObject& operator = (RuntimeObject x)
  {
    ori = x.ori;
    oci = x.oci;
  }
    boost::shared_ptr<RtmInfo> ori;
  boost::shared_ptr<CplInfo> oci;
};

FnInfo getFnParameters(const CplInfo& c);

#endif
